Перенаправление стандартных потов вводы вывода
=================================================

.. index::
    стандартный поток ввода
    стандартный поток вывода
    stdin
    stdout
    readf
    writeln

Все программы, которые мы видели до сих пор, взаимодействовали через stdin и
stdout, стандартные потоки ввода и вывода. Функции ввода и вывода, такие как
readf и writeln, работают с этими потоками по умолчанию.
При использовании этих потоков мы предполагали, что стандартный ввод осуществляется с
клавиатуры, а стандартный вывод выводится на экран.
Мы приступим к написанию программ, которые работают с файлами, в последующих главах. Мы увидим,
что, как и стандартные потоки ввода и вывода, файлы
также являются потоками символов; поэтому они используются почти так же, как stdin и stdout .
Но прежде чем увидеть, как осуществляется доступ к файлам из программ, я хотел бы
показать, как стандартные входные и выходные данные программ могут быть перенаправлены в файлы
или переданы по конвейеру в другие программы. Существующие программы можно, без изменения их исходного кода,
заставить печатать в файлах вместо экрана и считывать из файлов
вместо клавиатуры. Хотя эти функции напрямую не связаны с
языками программирования, они являются полезными инструментами, которые доступны почти во всех
современных оболочках.

Перенаправление стандартного потока вывода в файл оператором  >
---------------------------------------------------------------

.. index::
    >

Если мы запускаем программу  из командной строки на терминале, добавляя в конце команды
символ > и имя файла, мы перенаправляем стандартный поток вывода в указанный нами файл.
Всё что программа будет печатать в стандартный поток вывода будет записано в указанный файл.
Рассмотрим пример: программа, которая читает числ с плавающей точкой умножве его на 2,
затем печатает его в старндартный поток вывода

.. code-block:: d

    import std.stdio;

    void main()
    {
        double number;
        readf(" %s", &number);
        writeln(number * 2);
    }


Пусть программа называется by_two, её вывод будет записан в файл by_two_result.txt.
Если запустим программу из командной строки, используя вот такую команду

.. code-block:: console

    ./by_two > by_two_result.txt

Например, если мы введем число 1.2 с терминала, результат 2.4 появится в файле
by_two_result.txt

*Примечание Также программа не напечатает приглашение, она будет молча ожидать число*


Перенаправление стандартного потока ввода из файла при помощи опрератора <
--------------------------------------------------------------------------

.. index::
    <

Аналогично перенаправлению стандартного потока вывода при помощи оператора >, стандартный
поток ввода из файла может быть перенаправлен при помощи оператора <.
В этом случае программа будет читать данные из файла вместо ожидания ввода с клавиатуры
Для тестирования будем использовать программу, которая делит введенное число на 10

.. code-block:: d

    import std.stdio;

    void main()
    {
        double number;
        readf(" %s", &number);
        writeln(number / 10);
    }

Предположим, что файл by_two_result.txt существует и содержит число 2.4 после исполнения предыдущей программы.
Пусть также программа называется one_tenth. Мы можем перенаправить стандартный поток ввода для данной программа
на чтение из файла. Команда будет выглядеть так :

.. code-block:: console

    ./one_tenth < by_two_result.txt

This time the program will read from by_two_result.txt and print the result to
the terminal as 0.24 .

Программа будет читать данные из файла by_two_result.txt и напечатает результат на терминал

.. code-block:: console

    0.24

Перенаправление обоих стандартных потоков
-----------------------------------------

The operators > and < can be used at the same time:
Операторы < и > могут быть использованы одновременно

.. code-block:: console

    ./one_tenth < by_two_result.txt > one_tenth_result.txt

Создание конвейера данных при помощи опрератора  |
--------------------------------------------------

.. index::
    |
    конвейер

Заметим, что файл by_two_result.txt является посредником между двумя программами;
by_two записывает в нее, а one_tenth считывает из нее.
Оператор | передает стандартный вывод программы, которая находится на его левой
стороне, на стандартный ввод программы, которая находится на ее правой стороне и в этом случае
нет необходимости в промежуточном файле. Например, когда две вышеприведенные
программы объединяются, как показано в следующей строке, они совместно вычисляют одну пятую часть
входных данных:

.. code-block:: console

    ./by_two | ./one_tenth


Сначала by_two читает число с её ввода (Помним, что подсказка не отображается, программа просто ждёт число)
Затем by_two пишет результат в стандартный поток вывода. В нашем случае результата by_two появится
на стандартном вводе программы one_tenth, которая проведёт вычисления и напечатает результат

Упражнения
----------

Создайте конвейер из большего числа программ, например

.. code-block:: console

    ./one | ./two | ./three
